package com.wyt.common.tool;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * Created with IntelliJ IDEA.
 * Description:
 *
 * @Author: yuanhongjun
 * DateTime: 2021-07-09 09:13
 */
public class RollBackUtils {

    private static final ThreadLocal<RollBackContext> rollbackThreadLocal = new ThreadLocal<>();

    public static final void add(Callable<String> callable) {
        RollBackContext rollBackContext = rollbackThreadLocal.get();
        rollBackContext.add(callable);
    }

    public static final void init() {
        rollbackThreadLocal.set(new RollBackContext());
    }

    public static final void remover(Callable<String> callable) {
        RollBackContext rollBackContext = rollbackThreadLocal.get();
        rollBackContext.remover(callable);
    }

    public static final void executor() {
        RollBackContext rollBackContext = rollbackThreadLocal.get();
        rollBackContext.executor();
    }

    public static final void release() {
        RollBackContext rollBackContext = rollbackThreadLocal.get();
        rollBackContext.release();
    }


}

class RollBackContext implements Serializable {

    protected Logger logger = LoggerFactory.getLogger(RollBackContext.class);

    private List<Callable<String>> rollbackList = new ArrayList<>();

    public void add(Callable<String> callable) {
        rollbackList.add(callable);
    }

    public void remover(Callable<String> callable) {
        rollbackList.remove(callable);
    }

    public int getSize() {
        return rollbackList.size();
    }

    public void release() {
        rollbackList.clear();
    }

    public void executor() {
        Collections.reverse(rollbackList);
        rollbackList.forEach(r -> {
            try {
                String rollback = r.call();
                logger.info("====start to execute rollback====");
                logger.info(rollback);
                logger.info("====end to execute rollback====");
            } catch (Exception e) {
                logger.error("====roll back is error!!====", e);
            }
        });
    }
}
